/*! \brief
 * This is SortingTable javascript component
 * Please follow below step to use Pager component:
 * 1. create a table as below format:
 <table class="classnameOfTable">
 <thead>
    <tr>
         <th>sorting header column1</th>
         <th>sorting header column2</th>
         <th>sorting header column3</th>
         ...
     </tr>
 </thead>
 <tbody>
    <tr>
         <td>sorting content column1</td>
         <td>sorting content column2</td>
         <td>sorting content column3</td>
         ...
     </tr>
 </tbody>
 </table>
 * 2. insert below code in your js file

renderContent: function(){
    //SortingTable
    var strPathJs = homeBase + 'ui/table/SortingTable.js';
    Asset.javascript(strPathJs, {
        onLoad: function(){
            var options = {
                objTable: this.boxBD.getElement('.dataTable'), //object sortingTable which you want to sort
                arrSortingColumnIndex : [1,2,3,4] // determine which thead.th column add sorting mechanism, EX: [0,2] means thead.th[0] and thead.th[2] add sorting mechanism
            }
            new WFSortingTable(options);
        }.bind(this)
    });
}

// This class I found at http://madhatted.com/2008/1/11/the-joy-of-a-minimal-complete-javascript-table-sort
// I had modify it to fulfill our requirement
// The regexes in _loadConversions test a cell
// begin sorted for a match, then use that conversion for all elements on that
// column.
//
// Requires mootools Class, Array, Function, Element, Element.Selectors,
// Element.Event, and you should probably get Window.DomReady if you're smart.

 * \author William Su
 */


var WFSortingTable;
WFSortingTable = new Class({
    Implements: [Options],
    options : {
        objTable: {}, // EX : this.boxBD.getElement('.dataTable')
        arrSortingColumnIndex: [], // determine which thead.th column add sorting mechanism, EX: [0,2] means thead.th[0] and thead.th[2] add sorting mechanism
        //objCaller: {}, // EX : if modScopeList use Pager, in modScopeList/module.js ==> objCaller = this;
        callbackRefreshList: null //objCaller callback function to refresh Pager List
    },
    initialize: function(options) {
        this.setOptions(options);

        this.table = this.options.objTable;
        this.table.addClass('comSortingTable');

        this.tbody = this.table.getElementsByTagName('tbody')[0];

        this.hashHeaders = new Hash;
        this.arrTheadTh = this.table.getElements('thead th');
        this.arrTheadTh.each(function(header, index){
            if (this.options.arrSortingColumnIndex.contains(index)) {
                // switch <th>TextInTh</th> to <th><span>TextInTh</span></th>
                header.set('html','<span>'+header.getText()+'</span>');

                var header = $(header);
                //console.log(header.get('orderByColName'));
                this.hashHeaders.set(header.getText(), {column: index, 'orderByColName': header.get('orderByColName')});
                header.addEvent('mousedown', function(evt) {
                    var evt = new Event(evt);
                    //alert(this.options.callbackRefreshList);
                    //console.log(typeof(this.options.callbackRefreshList));
                    if(this.options.callbackRefreshList === '(an empty string)'){
                        this._sortByHeader(evt.target.getText());
                    }else{
                        this._sortByHeaderAjax(evt.target.getText());
                    }
                }.bind(this));
            }
        }.bind(this));

        this._loadConversions();
        return this;
    },

    _sortByHeaderAjax: function(header_text) {
        var header = this.hashHeaders.get(header_text);
        if (this.sort_column >= 0 && this.sort_column == header.column) {
            // If the this.rows already sorting by _compareRows
            // They were directly pulled off in reverse
            // skip the _compareRows effort

            // set the order_by_flag to handle the Asc and Desc icon
            this.order_by_flag *= -1;
        } else {
            // First time sorting
            // use _compareRows to sorting
            this.sort_column = header.column;
            this.order_by_flag = 1;
            this.order_by_column_name = header.orderByColName;
        }
        // update orderby Asc or Desc icon
        this._updateOrderByStatus();

        // call objCaller.refreshPagerList()
        //var callbackRefreshList = 'this.options.objCaller.'+this.options.callbackRefreshList+'();';
        //eval(callbackRefreshList);
        if(this.options.callbackRefreshList){
            this.options.callbackRefreshList.apply();
        }
    },

    _sortByHeader: function(header_text) {
        this.rows = new Array;
        var trs = this.tbody.getElements('tr');
        while (trs.length > 0) {
            var row = { row: trs.shift().remove() };
            this.rows.unshift(row);
        }

        var header = this.hashHeaders.get(header_text);
        if (this.sort_column >= 0 && this.sort_column == header.column) {
            // If the this.rows already sorting by _compareRows
            // They were directly pulled off in reverse
            // skip the _compareRows effort

            // set the order_by_flag to handle the Asc and Desc icon
            this.order_by_flag *= -1;
        } else {
            // First time sorting
            // use _compareRows to sorting
            this.sort_column = header.column;
            this.order_by_flag = 1;
            this.order_by_column_name = header.orderByColName;

            // determine the conversion_function
            if (header.conversion_function) {
                this.conversion_function = header.conversion_function;
            } else {
                this.conversion_function = false;
                this.rows.some(function(row) {
                    var to_match = $(row.row.getElementsByTagName('td')[this.sort_column]).getText();

                    //comment below because if all content td is empty will cause error
                    //if (to_match == ''){ return false }

                    this.conversions.some(function(conversion) {
                        if (conversion.matcher.test(to_match)) {
                            this.conversion_function = conversion.conversion_function;
                            return true;
                        }
                        return false;
                    }.bind(this));
                    if (this.conversion_function) {
                        return true;
                    }
                    return false;
                }.bind(this));
                header.conversion_function = this.conversion_function.bind(this);
                this.hashHeaders.set(header_text, header);
            }
            this.rows.each(function(row) {
                row.compare_value = this.conversion_function(row);
            }.bind(this));
            this.rows.sort(this._compareRows.bind(this));
        }

        // After sorting, inject result to table tbody
        var index = 0;
        while (this.rows.length > 0) {
            var row = this.rows.shift();
            row.row.injectInside(this.tbody);
            index++;
        }

        // empty this.rows
        this.rows = false;

        // update orderby Asc or Desc icon
        this._updateOrderByStatus();
    },

    _compareRows: function(r1, r2) {
        if (r1.compare_value > r2.compare_value) {
            return  1
        }
        if (r1.compare_value < r2.compare_value) {
            return -1
        }
        return 0;
    },
    _updateOrderByStatus: function() {
        var orderByColName = '';
        var orderByDirection = '';
        this.arrTheadTh.each(function(header, index) {
            if (this.options.arrSortingColumnIndex.contains(index)) {
                var header_span = header.getElement('span');
                if (index == this.sort_column) {
                    if (this.order_by_flag > 0) {
                        header_span.removeClass('comSortingTable_iconDesc');
                        header_span.addClass('comSortingTable_iconAsc');
                        orderByDirection = 'ASC';
                    }else{
                         header_span.removeClass('comSortingTable_iconAsc');
                         header_span.addClass('comSortingTable_iconDesc');
                         orderByDirection = 'DESC';
                    }
                    orderByColName = this.order_by_column_name;
                }else{
                    header_span.removeClass('comSortingTable_iconAsc');
                    header_span.removeClass('comSortingTable_iconDesc');
                }
            }

        }.bind(this));
        /*if(WF.util.isEmptyObject(this.options.objCaller) == false){
            this.options.objCaller.orderByColName = orderByColName;
            this.options.objCaller.orderByDirection = orderByDirection;
        }*/
        this.orderByColName = orderByColName;
        this.orderByDirection = orderByDirection;
    },
    _loadConversions: function() {
        this.conversions = $A([
            // YYYY-MM-DD, YYYY-m-d
            { matcher: /\d{4}-\d{1,2}-\d{1,2}/,
                conversion_function: function(row) {
                    var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).getText();
                    var re = /(\d{4})-(\d{1,2})-(\d{1,2})/;
                    cell = re.exec(cell);
                    return new Date(parseInt(cell[1]), parseInt(cell[2], 10) - 1, parseInt(cell[3], 10));
                }
            },
            // Fallback
            { matcher: /.*/,
                conversion_function: function(row) {
                    return $(row.row.getElementsByTagName('td')[this.sort_column]).getText();
                }
            }
        ]);
    }

});
